# -*- coding: utf-8 -*-
#pylint: disable-msg=E1101,W0212
'''
Created on 03/lug/2009

@author: sax
'''
from django import forms
from django.db import models
from django.utils.safestring import mark_safe
from django.core.urlresolvers import reverse, NoReverseMatch
from django.utils.encoding import StrAndUnicode, force_unicode

__all__=['ReadOnlyWidget', 'ModelLinkWidget', 'URLWidget', 'LabelWidget']

class LabelWidget(forms.HiddenInput, StrAndUnicode):

    def render(self, name, value, attrs=None):
        if value is None: value = ''
        final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
        return mark_safe(u'<span%s>%s</span>' % ( forms.util.flatatt(final_attrs), 
                                                  force_unicode(value)
                                                  )
        )
                 
class URLWidget(forms.TextInput):
    def __init__(self, attrs=None):
        final_attrs = {'class': 'xURLWidget'}
        if attrs is not None:
            final_attrs.update(attrs)
        super(URLWidget, self).__init__(attrs=final_attrs)
            
    def render(self, name, value, attrs=None):
        ret = super(URLWidget, self).render(name, value, attrs)
        if bool(value):
            ret += '<a class="xURLWidgetLink" target="_new" href="%s">&nbsp;&nbsp;&nbsp;</a>' % value
        return mark_safe(ret)                



class ReadOnlyWidget(forms.TextInput, StrAndUnicode):
    def __init__(self, obj, field_name, attrs=None, empty_value=""):
        
        self.attrs = attrs
        value = getattr(obj, field_name) if obj else None             
        self.empty_value = empty_value
        self.original_value = value
        
        if isinstance(value, models.Model):            
            self.display_value = str(value)
        elif value is None:
            self.display_value = empty_value
        else:
            display_func = getattr(obj, "get_%s_display" % field_name, None)
            if display_func:
                self.display_value = display_func()
            else:        
                self.display_value = unicode(value)

        super(ReadOnlyWidget, self).__init__( attrs )
    
    def value_from_datadict(self, data, files, name):
        """
        Given a dictionary of data and this widget's name, returns the value
        of this widget. Returns None if it's not provided.
        """
        return self.original_value
        #return data.get(name, None)
        
    def get_display_value(self):
        return mark_safe(u'<span class="xReadOnlyWidget">%s</span>' % self.display_value)
    
    def _has_changed(self, initial, data):
        return False
    
    def __unicode__(self):
        return unicode(self.__repr__())
    
    def render(self, name, value, attrs=None):
        return self.get_display_value()
#        if self.display_value != self.empty_value:
#            return super(ReadOnlyWidget, self).render(name, value, attrs) +\
#                    self.get_display_value()
#        else:
#            return self.empty_value

class HiddenValueWidget(ReadOnlyWidget, StrAndUnicode):
    def render(self, name, value, attrs=None):
        return "****"

class ModelLinkWidget( ReadOnlyWidget, StrAndUnicode ):
    def __init__(self, admin_site, obj, field_name, attrs=None, empty_value=""):
        self.admin_site = admin_site
        self.original_object = getattr(obj, field_name) if obj else None    
        super(ModelLinkWidget, self).__init__(obj, field_name, attrs, empty_value)
        
    def _get_model_change_link(self, model_instance):        
        info = ( str(self.admin_site.name), model_instance._meta.app_label, model_instance._meta.module_name )
        name='%s:%s_%s_change' % info
        try:            
            return reverse(name, args=(model_instance.pk,))
        except NoReverseMatch:
            raise NoReverseMatch("Error reversing %s" % name )
    
    def value_from_datadict(self, data, files, name):
        """
        Given a dictionary of data and this widget's name, returns the value
        of this widget. Returns None if it's not provided.
        """
        return self.original_object.pk
    
    def get_display_value(self):
        link =  self._get_model_change_link( self.original_object )
        label = force_unicode(self.display_value)
        return mark_safe(u'<a class="xModelLinkWidget" href="%s">%s</a>' % (link, label))
    
    
    
    
    
    